package org.example.smart.Client;

import com.briup.smart.env.client.Gather;
import com.briup.smart.env.entity.Environment;

import java.io.*;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

public class GatherBackupImpl implements Gather {

    @Override
    public Collection<Environment> gather() {
        System.out.println("带备份功能");
        // 读取备份文件 获取上一次的采集位置
        String backupFilePath = "D:\\JDBC_project\\ENV_project\\src\\main\\resources\\gather_backup.txt";
        // 获取偏移位置
        long offset = 0;
        // 读取文件
        File file = new File(backupFilePath);
        System.out.println(file);
        if (file.exists() && file.isFile() && file.length() > 0) {
            System.out.println("file");
            try (
                    // 读取文件
                    DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
                offset = dis.readLong();
                System.out.println("客户端：采集模块，上次的偏移位置" + offset);
                // 调整读取的偏移位置（注意只有采集到数据的时候才调整偏移位置）

            } catch (Exception e) {
                e.printStackTrace();
            } // 资源已关闭 try()
        }

        // 创建list 用于存放 Environment 类的对象
        ArrayList<Environment> list = new ArrayList<>();
        // 准备文件
        String filePath = "D:\\JDBC_project\\ENV_project\\src\\main\\resources\\data-file-simple";
        // String filePath = "src/main/resources/data-file";
        // File file = new File(filePath);
        // 根据偏移位置读取文件
        // 使用随机访问流 调整偏移位置
        RandomAccessFile raf = null;
        try {
            // 准备io流 读取文件内容
            raf = new RandomAccessFile(filePath, "r");
            // 调整偏移量
            raf.seek(offset);
            // 逐行读取
            String str = null;
            while ((str = raf.readLine()) != null) {
                offset += 2;
                // System.out.println(str);
                // 按字段拆分 | 提取有效信息
                String[] arr = str.split("[|]");
                // 创建 Environment 类的对象 将解析出来的数据给到对象
                Environment environment = new Environment();
                // 给 environment 对象赋值
                // 设置发送端id
                environment.setSrcId(arr[0]);
                // 设置树莓派系统id
                environment.setDesId(arr[1]);
                // 设置试验箱区域模块id
                environment.setDevId(arr[2]);
                // 设置模块上传感器地址 16表示温湿度
                environment.setSensorAddress(arr[3]);
                // 设置传感器个数
                environment.setCount(Integer.parseInt(arr[4]));
                // 设置指令标号 3表示接收数据 16表示发送命令
                environment.setCmd(arr[5]);
                // 设置环境数据 - 在下面switch中 - arr[6]
                // 设置状态标识
                environment.setStatus(Integer.parseInt(arr[7]));
                // 设置采集时间 把string类型的时间戳转化为时间戳对象
                environment.setGatherDate(new Timestamp(Long.parseLong(arr[8])));
                // 区分传感器类型
                switch (arr[3]) {
                    case "16":
                        // System.out.println("温湿度");
                        // 数据换算
                        // 表示温度和湿度数据。当数据为温度和湿度时，环境数据arr[6]（例:5d806ff802）的前两个字节表示温度(即前4位数,例:5d80)中间的两个字节表示湿度(即中间的4位数，例:6ff8)
                        String temperature = arr[6].substring(0, 4);
                        // System.out.println(temperature);
                        // 转化为实际数据
                        // 实际温度(data*(0.00268127F))-46.85F
                        int temperatureInt = Integer.parseInt(temperature, 16);
                        // 最终温度
                        // System.out.print("实际温度：");
                        // System.out.println();
                        // 设置环境数据 - arr[6]
                        environment.setName("温度");
                        environment.setData((temperatureInt * (0.00268127F)) - 46.85F);
                        // 将Environment对象保存到集合中
                        list.add(environment);
                        // 克隆 environment 对象
                        Environment environment1 = new Environment(
                                null, environment.getSrcId(), environment.getDesId(), environment.getDevId(),
                                environment.getSensorAddress(), environment.getCount(), environment.getCmd(), environment.getStatus(),
                                0,
                                environment.getGatherDate());
                        String humidity = arr[6].substring(4, 8);
                        int humidityInt = Integer.parseInt(humidity, 16);
                        // System.out.println(humidity);
                        // System.out.print("实际湿度：");
                        // System.out.println();
                        // 设置环境数据 - arr[6]
                        environment1.setName("湿度");
                        environment1.setData((humidityInt * 0.00190735F) - 6);
                        list.add(environment1);
                        break;
                    case "256":
                        // System.out.print("光照强度：");
                        // 数据换算
                        // System.out.println(Integer.parseInt(arr[6].substring(0, 4), 16));
                        environment.setName("光照强度：");
                        environment.setData((Integer.parseInt(arr[6].substring(0, 4), 16)));
                        list.add(environment);
                        break;
                    case "1280":
                        // System.out.print("二氧化碳浓度：")
                        // 数据换算
                        // System.out.println(Integer.parseInt(arr[6].substring(0, 4), 16));
                        environment.setName("二氧化碳浓度：");
                        environment.setData((Integer.parseInt(arr[6].substring(0, 4), 16)));
                        // 封装成Environment类的对象
                        // 将所有Environment类的对象保存到集合中
                        list.add(environment);
                        break;
                    default:
                        System.out.println("数据格式有误，请排查是否是新设备：\n" + str);
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 将本次采集的字节数 记录到文件中
            try (
                    DataOutputStream dos = new DataOutputStream(
                            new FileOutputStream(file));) {
                // 获取当前文件偏移量
                long currOffset = raf.getFilePointer();
                // 文件偏移量写入到备份文件中
                dos.writeLong(currOffset);
                System.out.println("客户端：采集模块，已记录偏移位置" + currOffset);
            } catch (Exception e) {
                e.printStackTrace();
            } // try() 自动关闭资源
            if (raf != null) {
                try {
                    raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 采集到的对象个数
        System.out.println("客户端：采集模块，采集到" + list.size() + "条数据");
        // // 遍历输出list
        // for (Environment environment : list) {
        // System.out.println(environment);
        // }
        return list;
    }
}
